www.gusucode.com > VC++ 仿Winamp自动停靠窗体-源码程序 > VC++ 仿Winamp自动停靠窗体-源码程序/code/DockWnd/DockDlg.cpp
//Download by http://www.NewXing.com // DockDlg.cpp : implementation file // #include "stdafx.h" #include "DockWnd.h" #include "DockDlg.h" #include "DockWndDlg.h" #include "math.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CDockDlg dialog CDockDlg::CDockDlg(CWnd* pParent /*=NULL*/) : CDialog(CDockDlg::IDD, pParent) { //{{AFX_DATA_INIT(CDockDlg) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT m_nDirection = BOTTOM; } void CDockDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CDockDlg) // NOTE: the ClassWizard will add DDX and DDV calls here //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CDockDlg, CDialog) //{{AFX_MSG_MAP(CDockDlg) ON_WM_CLOSE() ON_WM_MOVING() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CDockDlg message handlers void CDockDlg::OnClose() { // TODO: Add your message handler code here and/or call default CDockWndDlg *pWnd; pWnd = (CDockWndDlg *)this->FromHandle(m_hParent); pWnd->InverseState(); } BOOL CDockDlg::Init(HWND hParent) { m_hParent = hParent; return Create(IDD_DISPLAY,this->GetDesktopWindow()); } // 定义两个域值 #define THRESHOLD 1 #define GAP 30 void CDockDlg::Dock(UINT nDirection,CWnd *pWndMain) { // 得到主窗体矩形区域 CRect rectMain; pWndMain->GetWindowRect(&rectMain); // 进行停靠操作 m_nDirection = nDirection; if (nDirection == LEAVE) m_nDirection = NO_DIRECTION; // 不再停靠 else if (!IsDocking(rectMain,m_rectWnd,nDirection)) Dock(LEAVE,pWndMain); int nSep; switch (m_nDirection) { case LEFT: // 从左方停靠 nSep = rectMain.left - m_rectWnd.right; if (abs(nSep) > THRESHOLD && abs(nSep) <= GAP) { m_rectWnd.OffsetRect(nSep,0); Dock(LEFT,pWndMain); } else if (abs(nSep) > GAP) Dock(LEAVE,pWndMain); break; case RIGHT: // 从右边停靠 nSep = rectMain.right - m_rectWnd.left; if (abs(nSep) > THRESHOLD && abs(nSep) <= GAP) { m_rectWnd.OffsetRect(nSep,0); Dock(RIGHT,pWndMain); } else if (abs(nSep) > GAP) Dock(LEAVE,pWndMain); break; case TOP: // 从上边停靠 nSep = rectMain.top - m_rectWnd.bottom; if (abs(nSep) > THRESHOLD && abs(nSep) <= GAP) { m_rectWnd.OffsetRect(0,nSep); Dock(TOP,pWndMain); } else if (abs(nSep) > GAP) Dock(LEAVE,pWndMain); break; case BOTTOM: // 从下面停靠 nSep = rectMain.bottom - m_rectWnd.top; if (abs(nSep) > THRESHOLD && abs(nSep) <= GAP) { m_rectWnd.OffsetRect(0,nSep); Dock(BOTTOM,pWndMain); } else if (abs(nSep) > GAP) Dock(LEAVE,pWndMain); break; case NO_DIRECTION: // 子窗体未停靠 break; case LEAVE: // 不再是停靠状态 m_nDirection = NO_DIRECTION; } } UINT CDockDlg::GetDirection() const { return m_nDirection; } BOOL CDockDlg::OnInitDialog() { CDialog::OnInitDialog(); // TODO: Add extra initialization here CWnd *pWnd; pWnd = this->FromHandle(m_hParent); // 得到主窗体矩形 CRect rectMain; pWnd->GetWindowRect(&rectMain); // 获得自身矩形 this->GetWindowRect(&m_rectWnd); // 左对齐 m_rectWnd.right = rectMain.left + m_rectWnd.Width(); m_rectWnd.left = rectMain.left; // 开始将子窗体停靠在主窗体的下方 m_rectWnd.bottom = rectMain.bottom + m_rectWnd.Height(); m_rectWnd.top = rectMain.bottom; this->MoveWindow(&m_rectWnd); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } void CDockDlg::OnMoving(UINT fwSide, LPRECT pRect) { // TODO: Add your message handler code here // 得到自身矩形区域 m_rectWnd.CopyRect(pRect); // 得到主窗体指针 CWnd *pWnd; pWnd= this->FromHandle(m_hParent); Dock(m_nDirection,pWnd); *pRect = m_rectWnd; } BOOL CDockDlg::IsDocking(CRect &rectMain, CRect &rectMine, UINT nDirection) { if (nDirection == LEFT || nDirection == RIGHT) { if (rectMine.top >= rectMain.top && rectMine.top <= rectMain.bottom) return TRUE; else if (rectMine.bottom >= rectMain.top && rectMine.bottom <= rectMain.bottom) return TRUE; } else if (nDirection == TOP || nDirection == BOTTOM) { if (rectMine.left >= rectMain.left && rectMine.left <= rectMain.right) return TRUE; else if (rectMine.right >= rectMain.left && rectMine.right <= rectMain.right) return TRUE; } else if (nDirection == NO_DIRECTION) { if ((rectMine.left < rectMain.right && rectMine.left > rectMain.left) || (rectMine.right < rectMain.right && rectMine.right > rectMain.left)) { if (abs(rectMine.top - rectMain.bottom) <= GAP) { m_nDirection = BOTTOM; return TRUE; } else if (abs(rectMine.bottom - rectMain.top) <= GAP) { m_nDirection = TOP; return TRUE; } } if ((rectMine.top < rectMain.bottom && rectMine.top > rectMain.top) || (rectMine.bottom < rectMain.bottom && rectMine.bottom > rectMain.top)) { if (abs(rectMine.left - rectMain.right) <= GAP) { m_nDirection = RIGHT; return TRUE; } else if (abs(rectMine.right - rectMain.left) <= GAP) { m_nDirection = LEFT; return TRUE; } } } // nDirection == LEAVE 或者不在停靠状态 return FALSE; } CRect CDockDlg::GetRect() const { return m_rectWnd; }